package com.zto.sch.config;

import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @program: sch-diy-parent
 * @description:
 * @author: sch
 * @create: 2020-12-28 16:56
 **/
@Configuration
public class ShardingJdbcConfig {
    // 定义sharding-Jdbc数据源
    @Bean
    DataSource getShardingDataSource() throws SQLException {
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());
        Properties properties = new Properties();
        properties.put("sql.show", "true");
        DataSource dataSource = ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, properties);

        return dataSource;
    }

    @Bean
    public SqlSessionFactory getSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:com.zto.sch.mapper/*.xml"));

        //分页插件
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("helperDialect", "mysql");
        properties.setProperty("reasonable", "true");
        properties.setProperty("params", "pageNum=pageNum;pageSize=pageSize");
        pageInterceptor.setProperties(properties);

        //添加分页插件
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageInterceptor});


        return sqlSessionFactoryBean.getObject();
    }

    private Map<String, DataSource> createDataSourceMap() {
        Map<String, DataSource> dataSourceMap = new HashMap<>();

        //配置第一个数据源
        DriverManagerDataSource dataSource1 = new DriverManagerDataSource();
        dataSource1.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource1.setUsername("root");
        dataSource1.setPassword("root");
        dataSource1.setUrl("jdbc:mysql://127.0.0.1:3307/ds_0");
        dataSourceMap.put("ds_0", dataSource1);

        //配置第二个数据源
//        DriverManagerDataSource dataSource2 = new DriverManagerDataSource();
//        dataSource2.setDriverClassName("com.mysql.cj.jdbc.Driver");
//        dataSource2.setUsername("root");
//        dataSource2.setPassword("root");
//        dataSource2.setUrl("jdbc:mysql://127.0.0.1:3307/ds_1");
//        dataSourceMap.put("ds_1", dataSource2);

        return dataSourceMap;
    }

    private TableRuleConfiguration getOrderTableRuleConfiguration() {

        // 配置 t_user 表规则
        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("t_order", "ds_0.t_order_$->{1..2}");

        // 配置Order表规则  指定t_order表的数据分布情况，配置数据节点 ds_0.t_order_1,ds_0.t_order_2,ds_1.t_order_1,ds_1.t_order_2

        // 配置分库策略
//        orderTableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "ds_${order_id % 2 +1}"));
        // 配置分表策略
        orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order_$->{order_id % 2}"));
        //无效，实际开发中分区key手动生成
//        orderTableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "order_id"));

        return orderTableRuleConfig;
    }


}
